package com.sys.object.common.utils; 

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.ImageIcon;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import com.jhlabs.image.BoxBlurFilter;
import com.mortennobel.imagescaling.AdvancedResizeOp;
import com.mortennobel.imagescaling.ResampleOp;
/**
 * Description:图像处理工具
 * @author WUZHUO	
 */
public class ImgUtil {
	
	/**
	 * 说明：对给定的原始图片截取指定宽度、高度图片并保持到指定文件中
	 * @param src 原始图片
	 * @param dest 处理后存储图片
	 * @param w 指定宽度
	 * @param h 指定高度
	 * @return 返回处理状态
	 */
	public static boolean cutSquareImage(String src,String dest,int w,int h){
		try {
	        BufferedImage source = getBufferedImageByFile(src);
	        int width = source.getWidth(); 
	        int height = source.getHeight();
	        //需要处理的目标图片的宽、高必须小于原始图才进行图片处理
	        if(width>=w && height>=h){
		        int min = width/w;
		        if(min > height/h)
		        	min = height/h;
	        	BufferedImage rect = source.getSubimage((width-w*min)/2,(height-h*min)/2,w*min,h*min);;
		        String subfix = dest.substring(dest.lastIndexOf(".")+1);
		        if("".equals(subfix))
		        	subfix = "jpg";
		        return ImageIO.write(new ResampleOp(w, h).filter(rect, null), subfix, new File(dest)); 
	        }else{
	        	FileUtils.copyFile(new File(src), new File(dest));
	        	return true;
	        }
	    } catch (Exception e) {
			e.printStackTrace();
		}
		return false;
    }
	
	public static BufferedImage toBufferedImage(Image image) {
		if (image instanceof BufferedImage) {
			return (BufferedImage) image;
		}
		// This code ensures that all the pixels in the image are loaded
		image = new ImageIcon(image).getImage();
		// Determine if the image has transparent pixels; for this method's
		// implementation, see e661 Determining If an Image Has Transparent
		// Pixels
		// boolean hasAlpha = hasAlpha(image);
		// Create a buffered image with a format that's compatible with the
		// screen
		BufferedImage bimage = null;
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		try {
			// Determine the type of transparency of the new buffered image
			int transparency = Transparency.OPAQUE;
			/*
			 * if (hasAlpha) { transparency = Transparency.BITMASK; }
			 */
			// Create the buffered image
			GraphicsDevice gs = ge.getDefaultScreenDevice();
			GraphicsConfiguration gc = gs.getDefaultConfiguration();
			bimage = gc.createCompatibleImage(image.getWidth(null),image.getHeight(null), transparency);
		} catch (HeadlessException e) {
			// The system does not have a screen
		}

		if (bimage == null) {
			// Create a buffered image using the default color model
			int type = BufferedImage.TYPE_INT_RGB;
			// int type = BufferedImage.TYPE_3BYTE_BGR;//by wang
			/*
			 * if (hasAlpha) { type = BufferedImage.TYPE_INT_ARGB; }
			 */
			bimage = new BufferedImage(image.getWidth(null),image.getHeight(null), type);
		}
		// Copy image to buffered image
		Graphics g = bimage.createGraphics();
		// Paint the image onto the buffered image
		g.drawImage(image, 0, 0, null);
		g.dispose();
		return bimage;
	}
	
	public static BufferedImage getBufferedImageByFile(String file){
		ImageIcon icon;
		try {
			byte[] bytes = FileUtils.readFileToByteArray(new File(file));
			icon = new ImageIcon(bytes);
			return toBufferedImage(icon.getImage());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static BufferedImage getBufferedImageByStream(InputStream ips){
		
		ImageIcon icon;
		try {
			byte[] data = new byte[ips.available()];
			IOUtils.readFully(ips, data);
			icon = new ImageIcon(data);
			return toBufferedImage(icon.getImage());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	
	/** 
     * 接收输入流输生成图片 
     * @param input 
     * @param writePath 
     * @param width 
     * @param height 
     * @param format 
     * @return 
     */  
    public static boolean resizeImage(InputStream input, String writePath,  
            Integer width, Integer height, String format) {  
        try {  
            if(width<3) width = 3;
            if(height<3) height = 3;
            
            BufferedImage inputBufImage = ImageIO.read(input);  
//            log.info("转前图片高度和宽度：" + inputBufImage.getHeight() + ":"+ inputBufImage.getWidth());  
            ResampleOp resampleOp = new ResampleOp(width, height);// 转换  
            BufferedImage rescaledTomato = resampleOp.filter(inputBufImage,  
                    null);  
            ImageIO.write(rescaledTomato, format, new File(writePath));  
//            log.info("转后图片高度和宽度：" + rescaledTomato.getHeight() + ":"+ rescaledTomato.getWidth());  
            return true;  
        } catch (IOException e) {  
            e.printStackTrace();  
            return false;  
        }  
  
    }  
  

    /** 
     * 接收File输出图片 
     * @param file 
     * @param writePath 
     * @param width 
     * @param height 
     * @param format 
     * @return 
     */  
    public static boolean resizeImage(File file, String writePath, Integer width,  
            Integer height, String format) {  
        try {  
//            BufferedImage inputBufImage = ImageIO.read(file);  
            BufferedImage inputBufImage = getBufferedImageByFile(file.getPath());
            
            int imh = inputBufImage.getWidth();  
            int imw = inputBufImage.getHeight();  
            
            if(imh<width && imw<height){
            	/* 如果截取图片大小超过原图大小则不截取  */
            	copyImg(file.getAbsolutePath(),writePath);
                return true;  
            }
            if(width<3) width = 3;
            if(height<3) height = 3;
            
            inputBufImage.getType();  
//            log.info("转前图片高度和宽度：" + inputBufImage.getHeight() + ":"+ inputBufImage.getWidth());  
            ResampleOp resampleOp = new ResampleOp(width, height);// 转换  
            BufferedImage rescaledTomato = resampleOp.filter(inputBufImage,  
                    null);  
            ImageIO.write(rescaledTomato, format, new File(writePath));  
//            log.info("转后图片高度和宽度：" + rescaledTomato.getHeight() + ":"+ rescaledTomato.getWidth());  
            return true;  
        } catch (IOException e) {  
            e.printStackTrace();  
            return false;  
        }  
  
    }  

    public static boolean interceptImage(File file, int x,int y,int w,int h,double radio,String format) {  
        try {  

            BufferedImage rescaledTomato = ImageIO.read(file);  
            if(radio>0){
	            x = (int)(x/radio);
	            y = (int)(y/radio);
	            w = (int)(w/radio);
	            h = (int)(h/radio);
            }
//            int width = inputBufImage.getWidth(null);
//            int height = inputBufImage.getHeight(null);
//            if(x+w>width){
//            	w = width - x;
//            }
//            if(y+h>height){
//            	h = height - y;
//            }
            
            rescaledTomato = rescaledTomato.getSubimage(x,y,(w-1),(h-1));
            
         // 补白(必须是等比缩放才会补白)  
                //  
            int width = w-1-x;
            int height = h-1-y;
            
            BufferedImage image = new BufferedImage(width, height,  
                        BufferedImage.TYPE_INT_RGB);  
                Graphics2D g = image.createGraphics();  
                g.setColor(Color.white);  
                g.fillRect(0, 0, width, height);  
                if (width == rescaledTomato.getWidth(null))  
                    g.drawImage(rescaledTomato, 0, (height - rescaledTomato  
                            .getHeight(null)) / 2, rescaledTomato  
                            .getWidth(null), rescaledTomato.getHeight(null),  
                            Color.white, null);  
                else  
                    g.drawImage(rescaledTomato, (width - rescaledTomato  
                            .getWidth(null)) / 2, 0, rescaledTomato  
                            .getWidth(null), rescaledTomato.getHeight(null),  
                            Color.white, null);  
                g.dispose();  
                rescaledTomato = image;  
           
            ImageIO.write(rescaledTomato, format, file);
            return true;  
        } catch (IOException e) {  
            e.printStackTrace();  
            return false;  
        }  
  
    }
	
    
   
    
    public static int[] getFileWidthAndHeight(File file) {  
        try {  
        	  Image src = javax.imageio.ImageIO.read(file); //构造Image对象  
              int width=src.getWidth(null); //得到源图宽  
              int height=src.getHeight(null); //得到源图长  
              int[] obj = new int[2];
              obj[0] = width;
              obj[1] = height;
              return obj;  
        } catch (IOException e) {  
            e.printStackTrace(); 
            return null;
        }  
  
    } 
    
        
    public static boolean resize(String fromPath, String toPath, Integer width,  
            Integer height, boolean isOtherThan, boolean isFiller, String format) {  
        try {  
            // 将图片文件读入到缓存中  
//        	FileInputStream  fis=new FileInputStream(fromPath);
//            BufferedImage inImage = ImageIO.read(fis);  
            BufferedImage inImage = getBufferedImageByFile(fromPath);
            
//			String fileExtName =fromPath.substring(fromPath.lastIndexOf(".") + 1,fromPath.length()).toLowerCase();
//			if("gif".equals(fileExtName)){
//				/* 判断是动画图片则不切  */
//	            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("gif");
//	            if(it.hasNext()) {
//	                ImageReader reader = it.next();
//	                reader.setInput(ImageIO.createImageInputStream(new File(fromPath)));
//	                int count = reader.getNumImages(true);
//	                if(count>0){
//
//	                	copyImg(fromPath,toPath);
//		                return true;  
//	                }
//	            }
//			}
            		
            int imh = inImage.getWidth();  
            int imw = inImage.getHeight();  
			
            if(width<3) width = 3;
            if(height<3) height = 3;
            // System.out.println("转前图片高度和宽度：" + inImage.getHeight() + ":"+  
            // inImage.getWidth());  
            int scaledW = width;  
            int scaledH = height;  
            
            if(imh<scaledW && imw<scaledH){
            	/* 如果截取图片大小超过原图大小则不截取  */
            	copyImg(fromPath,toPath);
                return true;  
            }
            
            if (isOtherThan) {  

  
                double scale;  
                if (imh <= height && imw <= width)  
                    scale = 1;  
                else if (imh > imw)  
                    scale = (double) height / (double) imh;  
                else  
                    scale = (double) width / (double) imw;  
  
                scaledW = (int) (scale * imw);  
                scaledH = (int) (scale * imh);  
            }  
  
            // 将图片分辨率转成指定分辨率（高+宽）  
            AdvancedResizeOp resampleOp = new ResampleOp(scaledW, scaledH);  
            // 重新生成图片  
            BufferedImage rescaledTomato = resampleOp.filter(inImage, null);  
  
            // 是否补白(必须是等比缩放才会补白)  
            if (isFiller || isOtherThan) {  
                //  
                BufferedImage image = new BufferedImage(width, height,  
                        BufferedImage.TYPE_INT_RGB);  
                Graphics2D g = image.createGraphics();  
                g.setColor(Color.white);  
                g.fillRect(0, 0, width, height);  
                if (width == rescaledTomato.getWidth(null))  
                    g.drawImage(rescaledTomato, 0, (height - rescaledTomato  
                            .getHeight(null)) / 2, rescaledTomato  
                            .getWidth(null), rescaledTomato.getHeight(null),  
                            Color.white, null);  
                else  
                    g.drawImage(rescaledTomato, (width - rescaledTomato  
                            .getWidth(null)) / 2, 0, rescaledTomato  
                            .getWidth(null), rescaledTomato.getHeight(null),  
                            Color.white, null);  
                g.dispose();  
                rescaledTomato = image;  
            }
  
            // 将文件写入输入文件  
            ImageIO.write(rescaledTomato, format, new File(toPath));  
  
            // System.out.println("转后图片高度和宽度：" + rescaledTomato.getHeight() +  
            // ":"+ rescaledTomato.getWidth());  
            return true;  
        } catch (IOException e) {  
            e.printStackTrace();  
            return false;  
        }  
  
    }  
    
	private static void copyImg(String inputFile,String toPath) throws IOException{
		File   input_File   =   new   File(inputFile);
		File file_out = new java.io.File(toPath);
		FileInputStream in1 = new FileInputStream(input_File);
		FileOutputStream out1 = new FileOutputStream(file_out);
		byte[] bytes = new byte[1024];
		int c;
		while ((c = in1.read(bytes)) != -1) {
			out1.write(bytes, 0, c);
		}
		
		in1.close();
		out1.close();
	}
	
	
	/** 
     * 根据传入的图片坐标进行图片截取 
     *  
     * @param x1 X起点坐标 
     * @param x2 X终点坐标 
     * @param y1 Y起点坐标 
     * @param y2 Y终点坐标 
     * @param originPath 原始图片的存放路径 
     * @param savePath 截取后图片的存储路径 
     * @throws IOException 
     */  
    public static void scissor(int x1, int x2, int y1, int y2,  
            String originPath, String savePath) throws IOException {  
          
        FileInputStream is = null;  
        ImageInputStream iis = null;  
  
        try {  
              
            // 读取图片文件  
            is = new FileInputStream(originPath);  
  
            /* 
             * 返回包含所有当前已注册 ImageReader 的 Iterator， 
             * 这些 ImageReader 声称能够解码指定格式。 
             * 参数：formatName - 包含非正式格式名称 .（例如 "jpeg" 或 "tiff"）等 。 
             */  
            Iterator<ImageReader> it = ImageIO  
                    .getImageReadersByFormatName(getExtention(originPath)  
                            .toLowerCase());  
            ImageReader reader = it.next();  
            // 获取图片流  
            iis = ImageIO.createImageInputStream(is);  
  
            /* 
             * iis:读取源.true:只向前搜索，将它标记为 ‘只向前搜索’。 
             * 此设置意味着包含在输入源中的图像将只按顺序读取，可能允许  
             * reader 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。 
             */  
            reader.setInput(iis, true);  
  
            /* 
             * 描述如何对流进行解码的类，用于指定如何在输入时从 Java Image I/O 
             * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件  
             * 将从其 ImageReader 实现的 
             * getDefaultReadParam方法中返回 ImageReadParam 的实例。 
             */  
            ImageReadParam param = reader.getDefaultReadParam();  
  
            /* 
             * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域，通过 Rectangle 对象 
             * 的左上顶点的坐标（x，y）、宽度和高度可以定义这个区域。 
             */  
            Rectangle rect = new Rectangle(x1, y1, x2 - x1, y2 - y1);  
  
            // 提供一个 BufferedImage，将其用作解码像素数据的目标。  
            param.setSourceRegion(rect);  
  
            /* 
             * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象，并将 它作为一个完整的 
             * BufferedImage 返回。 
             */  
            BufferedImage bi = reader.read(0, param);  
  
            // 保存新图片  
            ImageIO.write(bi, getExtention(originPath).toLowerCase(), new File(  
                    savePath));  
        } finally {  
            if (is != null)  
                is.close();  
            if (iis != null)  
                iis.close();  
        }  
    }  
    
    /** 
     * 功能：提取文件名的后缀 
     *  
     * @param fileName 
     * @return 
     */  
    private static String getExtention(String fileName) {  
        int pos = fileName.lastIndexOf(".");  
        return fileName.substring(pos + 1);  
    }  
    
    
    /**
     * 水印
     * @return
     */
    public static boolean watermark(String fromPath, String toPath,int imageX,int imageY, int width,int height,String fileExtName){
    	BufferedImage srcimage= getBufferedImageByFile(fromPath); 
    	BufferedImage dstimage = null;
    	BufferedImage zitiimage = null;
		try {
			zitiimage = ImageIO.read(new File("/mnt/root/image/resource/watermark.png"));
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}  

    	int w = srcimage.getWidth();
    	int h = srcimage.getHeight();
    	
    	BufferedImage tmp = srcimage.getSubimage((w-imageX), (h-imageY), width, height);
    	BoxBlurFilter filter = new BoxBlurFilter();
    	
    	dstimage = filter.filter(tmp, null);
		
    	int tw = tmp.getWidth();
    	int th = tmp.getHeight();
    	
    	int sx = (tw - zitiimage.getWidth())/2;
    	int sy = (th - zitiimage.getHeight())/2;
    	if(sx < 0){
    		sx = 0;
    	}
    	if(sy < 0){
    		sy = 0;
    	}
    	dstimage.getGraphics().drawImage(zitiimage, sx, sy, null);
    	
    	for(int x = 0 ; x<tw; x++){
    		for(int y=0 ;y<th;y++){
    			int rgb = dstimage.getRGB(x, y);
    			srcimage.setRGB(x+w-imageX, y+h-imageY, rgb);
    		}
    	}
    	
    	try {
			return ImageIO.write(srcimage, fileExtName, new File(toPath));
		} catch (IOException e) {
			e.printStackTrace();
		} 
    	return true;
    }
}
